package com.zhxs.websocket;

import static com.zhxs.websocket.RequestData.WEB_SOCKET_HEART_CLIENT;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Nullable;

import com.zhxs.utils.LogUtil;
import com.zhxs.utils.SDCardUtil;
import com.google.gson.Gson;


import org.java_websocket.exceptions.WebsocketNotConnectedException;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.nio.ByteBuffer;
import java.util.List;

public class WebSocketService extends Service {
    public static final int COMMAND_SEND_TEXT = 2;
    public static final int COMMAND_START_AUDIO_PLAY = 7;
    public static final int COMMAND_STOP_AUDIO_PLAY = 8;
    public static final int COMMAND_START_RECORD_PLAY = 9;
    public static final int COMMAND_STOP_RECORD_PLAY = 10;
    public static final int COMMAND_SHOW_HIGH_TEMP = 11;
    public static final int COMMAND_DISMISS_HIGH_TEMP = 12;

    private static final String TAG = "WebSocketService";
    public WebSocketClientImpl client;
    private SocketServiceBinder socketBinder = new SocketServiceBinder();

    private IMsgCallback msgCallback;
    //接受服务器最后一次心跳的时间
    private long lastSendTime = 0;

    @Override
    public void onCreate() {
        LogUtil.d("onCreate");

        mHeartHandler.sendEmptyMessageDelayed(REFRESH_HEART_WHAT, HEART_BEAT_RATE);
        initWebSocket();
//        acquireWakeLock();
        super.onCreate();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        LogUtil.d("onBind");
        return socketBinder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtil.d("onStartCommand");
//        if (intent != null){
            int command = intent.getIntExtra("command",-1);
            switch (command){
                case COMMAND_SEND_TEXT:
                    String text = intent.getStringExtra("text");
                    if(!TextUtils.isEmpty(text)){
                        sendMsg(text);
                    }
                    break;
            }
//        }
        return START_NOT_STICKY;
    }

    public static void sendStartRecordCmd(Context context) {
        Intent intent = new Intent(context, WebSocketService.class);
        intent.putExtra("command", COMMAND_START_RECORD_PLAY);
        context.startService(intent);
    }

    public static void sendStopRecordCmd(Context context) {
        Intent intent = new Intent(context, WebSocketService.class);
        intent.putExtra("command", COMMAND_STOP_RECORD_PLAY);
        context.startService(intent);
    }

    public static void sendText(Context context ,String txt) {
        Intent intent = new Intent(context, WebSocketService.class);
        intent.putExtra("command", COMMAND_SEND_TEXT);
        intent.putExtra("text", txt);
        context.startService(intent);
    }

    public static void startPlay(Activity context) {
        Intent intent = new Intent(context, WebSocketService.class);
        intent.putExtra("command",COMMAND_START_AUDIO_PLAY);
        context.startService(intent);
    }

    public static void stopPlay(Activity context) {
        Intent intent = new Intent(context, WebSocketService.class);
        intent.putExtra("command",COMMAND_STOP_AUDIO_PLAY);
        context.startService(intent);
    }

    public static void sendShowHighTempCmd(Context context) {
        Intent intent = new Intent(context, WebSocketService.class);
        intent.putExtra("command", COMMAND_SHOW_HIGH_TEMP);
        context.startService(intent);
    }

    public static void sendDismissHighTemp(Context context) {
        Intent intent = new Intent(context, WebSocketService.class);
        intent.putExtra("command", COMMAND_DISMISS_HIGH_TEMP);
        context.startService(intent);
    }

    private void sendStartAudioRecordCmd() {
        RequestData requestData = new RequestData();
        requestData.setCode(RequestData.AUDIO_START_RECORD_PLAY);
        sendMsg(new Gson().toJson(requestData));
    }

    private void sendStopAudioRecordCmd() {
        RequestData requestData = new RequestData();
        requestData.setCode(RequestData.AUDIO_STOP_RECORD_PLAY);
        sendMsg(new Gson().toJson(requestData));
    }



    @Override
    public boolean onUnbind(Intent intent) {
        LogUtil.d("onUnbind");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        LogUtil.d("onDestroy");
        mHeartHandler.removeCallbacksAndMessages(null);
        closeConnect();

        if (wakeLock != null) {
            wakeLock.release();
        }
        super.onDestroy();
    }

//    private boolean isFirstCome = true;

    private void initWebSocket() {
//        String localIp = SDCardUtil.loadServerFromSDFile();
//        if (TextUtils.isEmpty(localIp)){
//            localIp = NetWorkUtils.getLocalIPAddress(this);
//        }
////        localIp = "172.20.10.3";
//        String deviceId = "001"; //标签 从配置文件获取
//        deviceId = SDCardUtil.loadIdFromSDFile();
//        String deviceType = "1"; //主机是1
        //老版 暂时用 后续会修改
//        String host = "ws://"+localIp+"platform/webSocketServer/00";

        //新版
        String deviceId = "ceshi"; //区域 从配置文件获取
        String serverIp =  "playerFileConfig.getServerIp()";

        //定义userID-1表示推送一键撤退给面罩如23001-1，userID-2表示推送图文给腕表23001-2，后面有新产品连接类推
        //新版
        String host = "ws://"+serverIp+"/sgserver/websocketServer/"+deviceId + "-2";
        LogUtil.d("host:"+host);
        URI uri = URI.create(host);
        client = new WebSocketClientImpl(uri){
            @Override
            public void onOpen(ServerHandshake handshakedata) {
                super.onOpen(handshakedata);
                lastSendTime = System.currentTimeMillis();
                LogUtil.e("websocket连接成功");

//                if (isFirstCome){
//                    isFirstCome = false;
//                }else {
//                    if (iConnCallback != null){
//                        iConnCallback.onConnect();
//                    }
//                }
            }

            @Override
            public void onMessage(ByteBuffer bytes) {
                super.onMessage(bytes);
                LogUtil.e("onMessage:"+bytes.array().length);
//                addToPlayQueue(bytes);

            }

            @Override
            public void onMessage(String message) {
                super.onMessage(message);
                LogUtil.i("onMessage:"+message);
                try {
                    RequestData requestData = new Gson().fromJson(message, RequestData.class);
                    if (requestData.getCode() == RequestData.WEB_SOCKET_HEART){
                        lastSendTime = System.currentTimeMillis();
                        sendMsg(message);
                    }
                    else if (requestData.getCode() == RequestData.WEB_SOCKET_TEXT_MSG){
                        String txt = (String) requestData.getMessage();
                        LogUtil.i("onMessage txt:"+txt);
                        //收到文字信息
                        if (msgCallback != null){
                            msgCallback.onMessageText(txt);
                        }

                    }else if (requestData.getCode() == RequestData.WEB_SOCKET_PICTURE_MSG){
                        //收到图片信息
                        String base64 = (String) requestData.getMessage();
                        if (msgCallback!=null){
                            msgCallback.onMessagePic(base64);
                        }
                    }

                } catch (Exception e){
                    LogUtil.e("onMessage:"+message+" 解析异常");
                }
            }

            @Override
            public void onError(Exception ex) {
                super.onError(ex);
                LogUtil.e("onError:"+ ex.getMessage());
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                super.onClose(code, reason, remote);
                LogUtil.e("onClose: code:"+ code + " reason:"+reason);
            }
        };
        connectWebSocket();
    }

    /**
     * 进行连接
     */
    private void connectWebSocket() {
        new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    client.connectBlocking();
                } catch (InterruptedException e) {
                    LogUtil.e("websocket连接失败:" + e.getMessage());
                }
            }
        }.start();
    }

    /**
     * 开启重连
     */
    private void reconnectWs() {
        mHeartHandler.removeMessages(REFRESH_HEART_WHAT);
        new Thread() {
            @Override
            public void run() {
                try {
                    LogUtil.i("开启重连");
                    client.reconnectBlocking();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    /**
     * @param msg 发送消息
     */
    public void sendMsg(String msg) {
        if (null != client) {
            if (client.isOpen()){
                try {
                    client.send(msg);
                } catch (WebsocketNotConnectedException conn){
                    LogUtil.i("发送异常:"+ conn.getMessage());
                }
            } else {
                LogUtil.e("client 连接已关闭 消息发送失败");
            }
        } else {
            LogUtil.e("client == null 消息发送失败");
        }
    }




    /**
     * 断开连接
     */
    private void closeConnect() {
        try {
            if (null != client) {
                client.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client = null;
        }
    }

    PowerManager.WakeLock wakeLock;//锁屏唤醒

    //获取电源锁，保持该服务在屏幕熄灭时仍然获取CPU时，保持运行
    @SuppressLint("InvalidWakeLockTag")
    private void acquireWakeLock()
    {
        if (null == wakeLock)
        {
            PowerManager pm = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
            wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE, "PostLocationService");
            if (null != wakeLock)
            {
                wakeLock.acquire();
            }
        }
    }

    //    -------------------------------------websocket心跳检测------------------------------------------------
    private static final long HEART_BEAT_RATE = 10 * 1000;//每隔10秒进行一次对长连接的心跳检测
    private static final int REFRESH_HEART_WHAT = 999;
    private Handler mHeartHandler = new Handler(new HeartCallback());

    private class HeartCallback implements Handler.Callback{
        @Override
        public boolean handleMessage(Message msg) {
            if (msg.what == REFRESH_HEART_WHAT){
                LogUtil.d("检测websocket 20秒的连接状态");

                //如果上次发出消息的时间超出20秒 判定为失败
                if (System.currentTimeMillis() - lastSendTime >= HEART_BEAT_RATE * 2){
                    LogUtil.e("20秒未收到心跳");
                    closeConnect();
                    initWebSocket();
                } else {
                    if (client != null) {
                        if (client.isClosed()) {
                            closeConnect();
                            initWebSocket();
                        } else {
                            LogUtil.d("发送心跳到服务器");
                            RequestData<String> requestData = new RequestData<>();
                            requestData.setCode(WEB_SOCKET_HEART_CLIENT);
                            sendMsg(new Gson().toJson(requestData));
                        }
                    } else {
                        //如果client已为空，重新初始化连接
                        client = null;
                        initWebSocket();
                    }
                }

                mHeartHandler.sendEmptyMessageDelayed(REFRESH_HEART_WHAT, HEART_BEAT_RATE);
            }
            return false;
        }
    }

    public class SocketServiceBinder extends Binder{
        public void registerCallBack(IMsgCallback cb){
            msgCallback = cb;
        }

        public void unRegisterCallBack(){
            msgCallback = null;
        }

    }

    /**
     * 判断某个服务是否正在运行的方法
     *
     * @param mContext
     * @param serviceName
     *            是包名+服务的类名（例如：net.loonggg.testbackstage.TestService）
     * @return true代表正在运行，false代表服务没有正在运行
     */
    public boolean isServiceWork(Context mContext, String serviceName) {
        boolean isWork = false;
        ActivityManager myAM = (ActivityManager) mContext
                .getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> myList = myAM.getRunningServices(Integer.MAX_VALUE);
        if (myList.size() <= 0) {
            return false;
        }
        for (int i = 0; i < myList.size(); i++) {
            String mName = myList.get(i).service.getClassName().toString();
            Log.i(TAG, "mName："+ mName);
            if (mName.equals(serviceName)) {
                isWork = true;
                break;
            }
        }
        return isWork;
    }
}
